package com.wing.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.extra.mail.Mail;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.CodeUtil;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.Result;
import com.wing.enterprise.feign.EnterpriseClient;
import com.wing.enterprise.product.model.response.ProductPackVO;
import com.wing.order.dao.*;
import com.wing.order.model.entity.*;
import com.wing.order.model.request.PurchaseForm;
import com.wing.order.model.response.OrderDeliverySignVO;
import com.wing.order.model.response.PurchaseBarCodeVo;
import com.wing.order.model.response.PurchaseVO;
import com.wing.product.model.entity.ProductPackLabel;
import com.wing.product.service.ProductPackLabelService;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 采购-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, Purchase> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private DynamicService dynamicService;

    @Autowired
    private EnterpriseClient enterpriseClient;

    @Autowired
    private DynamicDao dynamicDao;

    @Autowired
    private OrderDeliverySignDao orderDeliverySignDao;

    @Autowired
    private InventoryJobSignProductDao signProductDao;

    @Autowired
    private InventoryJobSignProductDetailDao SignProductDetailDao;

    @Autowired
    InventoryInoutDao inventoryInoutDao;

    @Autowired
    private EnterpriseClient productDetailClient;

    @Autowired
    private InventoryJobLabelDao inventoryJobLabelDao;

    @Autowired
    private InventoryJobLabelDao jobLabelDao;

    @Autowired
    private OrderDeliverySignDetailDao orderDeliverySignDetailDao;

    @Autowired
    private ProductPackLabelService productPackLabelService;


    @Override
    public int add(PurchaseForm purchaseForm) {

        //校验

        Purchase purchase = new Purchase();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(Purchase.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(purchaseForm, purchase, copyOptions);

        return baseMapper.insert(purchase);
    }

    @Override
    public List<PurchaseVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<PurchaseVO> pageList4app(Page page, Map<String, Object> params) {
        List<PurchaseVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public PurchaseVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }


    @Transactional
    @Override
    public int addPurchase(PurchaseForm purchaseForm) {
        // 校验采购数量是否大于库存数量
/*        for (int i = 0; i < purchaseForm.getPurchaseDetailList().size(); i++) {
            if (purchaseForm.getPurchaseDetailList().get(i).getNum() > purchaseForm.getPurchaseDetailList().get(i).getStockNumber()) {
                throw new BusinessException("采购数量大于库存数量");
            }
        }*/
        //校验产品金额是否从库存产品带出
        for (int i = 0; i < purchaseForm.getPurchaseDetailList().size(); i++) {
            if (purchaseForm.getPurchaseDetailList().get(i).getMarketPrice()==0){
                return 0;
            }
        }
        List<Integer> orderMoneyList = new ArrayList();
        Purchase purchase = new Purchase();
        BeanUtil.copyProperties(purchaseForm, purchase);
        // 设置采购单编号
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String code = dynamicService.getDayNextCode("ord_purchase");
        String day = simpleDateFormat.format(new Date());
        purchase.setCode("CG-" + day + "-" + code);
        purchase.setDay(Integer.valueOf(day));
        purchase.setNo(Integer.valueOf(code));
        // 采购申请人
        purchase.setCreatorName(JwtUtils.getLoginUsername());
        purchase.setId(null);
        // 添加主表
        if (!this.save(purchase)) {
            throw new BusinessException("采购产品添加失败");
        }
        // 添加详情
        PurchaseDetail purchaseDetail = new PurchaseDetail();
        for (int i = 0; i < purchaseForm.getPurchaseDetailList().size(); i++) {

            //修改在库列表的库存数
     /*       JsonResult result = enterpriseClient.upById(purchaseForm.getPurchaseDetailList().get(i).getId(),purchaseForm.getPurchaseDetailList().get(i).getNum());
            if (result.getCode()!=200){
                throw new BusinessException("库存数量修改失败");
            }*/
            //校验是否存在该产品
//            QueryWrapper<PurchaseDetail>queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("sku_code",purchaseForm.getPurchaseDetailList().get(i).getSkuCode());
//            PurchaseDetail detail = purchaseDetailService.getOne(queryWrapper);
//            if (detail==null){
            BeanUtil.copyProperties(purchaseForm.getPurchaseDetailList().get(i), purchaseDetail);
            // 设置小计金额
            purchaseDetail.setAmount(BigDecimal.valueOf(purchaseForm.getPurchaseDetailList().get(i).getNum() * purchaseForm.getPurchaseDetailList().get(i).getMarketPrice()));
            purchaseDetail.setPurchaseId(purchase.getId());
            // 设置主表的总计
            orderMoneyList.add(purchaseForm.getPurchaseDetailList().get(i).getAmount());
            purchaseDetail.setId(null);
            if (!purchaseDetailService.save(purchaseDetail)) {
                throw new BusinessException("采购产品详情添加失败");
            }
            /* } else {
                detail.setNum(detail.getNum()+purchaseForm.getPurchaseDetailList().get(i).getNum());
                purchaseDetailService.updateById(detail);
            }*/
        }
        // 设置订单金额
        Purchase purchase1 = this.getById(purchase.getId());
        Integer count = 0;
        for (int i = 0; i < orderMoneyList.size(); i++) {
            count += orderMoneyList.get(i);
        }
        purchase1.setOrderMoney(count);
        if (!this.updateById(purchase1)) {
            throw new BusinessException("修改订单金额失败");
        }


        return 1;
    }

    @Override
    public PurchaseVO getPurchaseByCode(String code) {
        PurchaseVO vo = baseMapper.getPurchaseByCode(code);
        /*for (int i = 0; i <vo.getPurchaseDetailList().size() ; i++) {
            if (vo.getPurchaseDetailList().get(i).getStatus().name().equals("isSign")){
                vo.getPurchaseDetailList().remove(i);
            }
        }*/
        return vo;
    }

    @Transactional
    @Override
    public void purchaseSign(PurchaseForm purchaseForm) {
        if (CollectionUtils.isEmpty(purchaseForm.getPurchaseDetailList())) {
            throw new BusinessException("签收参数异常");
        }
        Purchase purchase = this.getById(purchaseForm.getId());
        if (purchase == null) {
            throw new BusinessException("当前签收的采购计划计划不存在");
        }

        // 签收记录
        OrderDeliverySign orderDeliverySign = new OrderDeliverySign();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        String today = format.format(date);
        Integer maxCode = dynamicDao.getDayMaxNo("ord_order_delivery_sign");
        String maxNo = CodeUtil.getCode(maxCode);
        OrderDeliverySignVO signVO = orderDeliverySignDao.get4appById(purchaseForm.getId());
//          if (signVO==null){
              orderDeliverySign.setCode("CGQS" + today + maxNo);
              orderDeliverySign.setNo(Integer.valueOf(maxNo));
              orderDeliverySign.setDay(Integer.valueOf(today));
              orderDeliverySign.setPlanId(purchase.getId());
              orderDeliverySign.setSignType(OrderDeliverySign.SignType.purchase);
              orderDeliverySign.setCreatorName(JwtUtils.getLoginUsername());
              orderDeliverySign.setCreateTime(LocalDateTime.now());
              orderDeliverySignDao.insert(orderDeliverySign);
//          }
            // 签收产品主表
            InventoryJobSignProduct signProduct = new InventoryJobSignProduct();
            signProduct.setSignId(orderDeliverySign.getId())
                    .setPlanId(purchase.getId());
            signProductDao.insert(signProduct);


        // 签收产品详情
        for (int i = 0; i < purchaseForm.getPurchaseDetailList().size(); i++) {
            // 查询产品名称
            QueryWrapper<PurchaseDetail>purchaseDetailQueryWrapper = new QueryWrapper<>();
            purchaseDetailQueryWrapper.eq("purchase_id",purchaseForm.getId());
            purchaseDetailQueryWrapper.eq("sku_code",purchaseForm.getPurchaseDetailList().get(i).getSkuCode());
            PurchaseDetail purchaseDetail1 = purchaseDetailService.getOne(purchaseDetailQueryWrapper);

            InventoryJobSignProductDetail signProductDetail = new InventoryJobSignProductDetail();
            signProductDetail.setSignId(orderDeliverySign.getId())
                    .setPlanId(purchase.getId())
                    .setSignProductId(signProduct.getId())
                    .setSkuCode(purchaseForm.getPurchaseDetailList().get(i).getSkuCode())
                    .setProductName(purchaseDetail1.getProductName())
                    .setUnitId(purchaseForm.getPurchaseDetailList().get(i).getUnitId())
                    .setProductType(purchaseForm.getPurchaseDetailList().get(i).getProductType())
                    .setUnitName(purchaseForm.getPurchaseDetailList().get(i).getUnitName())
                    .setAmount(purchaseForm.getPurchaseDetailList().get(i).getAmount());
            SignProductDetailDao.insert(signProductDetail);
            // 签收记录明细
            OrderDeliverySignDetail orderDeliverySignDetail = new OrderDeliverySignDetail();
            orderDeliverySignDetail.setSignId(orderDeliverySign.getId())
                                    .setSkuCode(purchaseForm.getPurchaseDetailList().get(i).getSkuCode())
                                    .setQuantity(purchaseForm.getPurchaseDetailList().get(i).getNum())
                                    .setStatus(OrderDeliverySignDetail.Status.signed);
            orderDeliverySignDetailDao.insert(orderDeliverySignDetail);

            // 添加产品包装条码
            // 包装方案  由页面选择包装方式 带过来的包装方案id
/*            JsonResult<ProductPackVO> packJson = productDetailClient.getProductPackById((purchaseForm.getPurchaseDetailList().get(i).getPackId()));
            purchaseForm.getPurchaseDetailList().get(i).setPackName(packJson.getData().getName());
            purchaseForm.getPurchaseDetailList().get(i).setPackId(packJson.getData().getId());*/
            // 页面填写的包装数量
//            double ceil = Math.ceil(purchaseForm.getPurchaseDetailList().get(i).getNum() / purchaseForm.getPurchaseDetailList().get(i).getBaseRate());
            Integer snNum = purchaseForm.getPurchaseDetailList().get(i).getPackNum();

            com.wing.product.model.request.ProductPackLabelForm productPackLabelForm = new com.wing.product.model.request.ProductPackLabelForm();
            productPackLabelForm.setSkuCode(purchaseForm.getPurchaseDetailList().get(i).getSkuCode());
            productPackLabelForm.setProductionManager(purchaseForm.getOrderAuditor());
            productPackLabelForm.setProductUnitId(purchaseForm.getPurchaseDetailList().get(i).getUnitId());
            productPackLabelForm.setPackId(purchaseForm.getPurchaseDetailList().get(i).getPackId());
            productPackLabelForm.setBatchCode(orderDeliverySign.getCode());
            productPackLabelForm.setAddCount(snNum);
            // 包装方式(多少一包装)
            productPackLabelForm.setQuantity(purchaseForm.getPurchaseDetailList().get(i).getBaseRate());
            // 送料数 -> 采购数
            productPackLabelForm.setFeedQuantity(purchaseForm.getPurchaseDetailList().get(i).getNum());
            productPackLabelForm.setInoutTypeCode("purchase");
            productPackLabelForm.setInoutTypeName("采购入库");
            productPackLabelForm.setRateType(com.wing.product.model.entity.ProductPackLabel.RateType.fixed);
            productPackLabelForm.setStatus(com.wing.product.model.entity.ProductPackLabel.Status.created);
            productPackLabelForm.setCreator(JwtUtils.getLoginUserId());
            productPackLabelForm.setCreatorName(JwtUtils.getLoginUsername());
            productPackLabelForm.setPurchaseId(purchaseForm.getId());
            // 添加产品包装条码
//            JsonResult labelNew = enterpriseClient.addProductPackLabelNew(productPackLabelForm);
             productPackLabelService.inertPackIndex2(productPackLabelForm);

            // 根据采购id skuCode查询pack所有条码
//            JsonResult<List<ProductPackLabel>> packLabelList = enterpriseClient.getByPurchaseId(purchaseForm.getId(), purchaseForm.getPurchaseDetailList().get(i).getSkuCode());
            JsonResult<List<ProductPackLabel>> packLabelList = productPackLabelService.getByPurchaseId(purchaseForm.getId(), purchaseForm.getPurchaseDetailList().get(i).getSkuCode());
            for (int j = 0; j < packLabelList.getData().size(); j++) {
                // 签收的包装条码
                InventoryJobLabel jobLabel = new InventoryJobLabel();
                jobLabel.setPlanId(purchase.getId())
                        .setSignId(orderDeliverySign.getId())
                        .setPackLabeQuantity(Long.valueOf(packLabelList.getData().get(j).getQuantity()))
                        .setQuantity(Long.valueOf(packLabelList.getData().get(j).getQuantity()))
                        .setStatus(InventoryJobLabel.Status.sign)
                        .setInoutType(InventoryJobLabel.InoutType.in)
                        .setPackLabeId(packLabelList.getData().get(j).getId())
                        .setPackLabeCode(packLabelList.getData().get(j).getCode())
                        .setInoutTypeCode("purchase")
                        .setInoutTypeName("采购入库")
                        .setSignProductDetailId(signProductDetail.getId())
                        .setPackId(purchaseForm.getPurchaseDetailList().get(i).getPackId())
                        .setPackName(purchaseForm.getPurchaseDetailList().get(i).getPackName());
                jobLabelDao.insert(jobLabel);
            }
            // 修改计划表 产品为已签收
            QueryWrapper<PurchaseDetail> detailQueryWrapper = new QueryWrapper<>();
            detailQueryWrapper.eq("purchase_id", purchaseForm.getId());
            detailQueryWrapper.eq("sku_code", purchaseForm.getPurchaseDetailList().get(i).getSkuCode());
            PurchaseDetail detail = purchaseDetailService.getOne(detailQueryWrapper);
            detail.setStatus(PurchaseDetail.Status.isSign);
            purchaseDetailService.updateById(detail);
        }
        // 校验该采购单下的产品是否签收完成
        PurchaseVO purchaseVO = getPurchaseByCode(purchaseForm.getCode());
        int num = 0;
        for (int i = 0; i < purchaseVO.getPurchaseDetailList().size(); i++) {
            if (purchaseVO.getPurchaseDetailList().get(i).getStatus().name().equals("isSign")) {
                num += 1;
            }
        }
        // 表示采购单下所有产品已签收则修改状态
        if (purchaseVO.getPurchaseDetailList().size() == num) {
            Purchase purchase1 = this.getById(purchaseForm.getId());
            purchase1.setStatus(Purchase.Status.isSign);
            this.updateById(purchase1);
        }else {
            // 修改状态为签收中
            Purchase purchase1 = this.getById(purchaseForm.getId());
            purchase1.setStatus(Purchase.Status.inSign);
            this.updateById(purchase1);
        }
    }

    @Override
    public IPage<PurchaseBarCodeVo> getLableBySignId(Integer page, Integer limit,Long id) {
        Page<PurchaseBarCodeVo> iPage = new Page<>(page, limit);
        Page<PurchaseBarCodeVo> lableList = baseMapper.getLableBySignId(iPage, id);
        return lableList;
    }

}
